`timescale 1ns / 1ps

module multiplier_4x4(
    input clk,                   // 时钟输入
    input clr_n,                 // 异步低电平复位
    input wire [3:0] a,          // 4位输入数a (乘数)
    input wire [3:0] b,          // 4位输入数b (被乘数)

    // 数码管显示输出 (逻辑保持不变)
    output wire [6:0] a_to_g,    
    output wire [3:0] an,        

    // 乘法运算结果输出
    output wire [1:0] led_hundreds,      
    output wire [3:0] result_tens_bcd,   
    output wire [3:0] result_units_bcd   
);

    // a 和 b 的 BCD 拆分（用于数码管显示）
    reg [3:0] a_tens, a_units;
    reg [3:0] b_tens, b_units;

    always @(*) begin
        a_tens  = (a >= 10) ? 1 : 0;
        a_units = (a >= 10) ? a - 10 : a;

        b_tens  = (b >= 10) ? 1 : 0;
        b_units = (b >= 10) ? b - 10 : b;
    end

    // 不用for循环实现移位加法乘法器
    reg [7:0] a_shifted;
    reg [7:0] partial0, partial1, partial2, partial3;
    reg [7:0] product_temp;
    

always @(*) begin
    a_shifted = {4'b0000, a};  // 4位乘数左侧补0扩展到8位

    // 生成每一位乘数对应的部分积
    partial0 = b[0] ? (a_shifted << 0) : 8'd0;
    partial1 = b[1] ? (a_shifted << 1) : 8'd0;
    partial2 = b[2] ? (a_shifted << 2) : 8'd0;
    partial3 = b[3] ? (a_shifted << 3) : 8'd0;

    // 将所有部分积相加
    product_temp = partial0 + partial1 + partial2 + partial3;
end

    wire [7:0] product_binary;
    assign product_binary = product_temp;

    // 二进制转 BCD
    reg [3:0] product_hundreds_reg;
    reg [3:0] product_tens_reg;
    reg [3:0] product_units_reg;
    reg [6:0] remainder_after_hundreds;

    always @(*) begin
        if (product_binary >= 200) begin
            product_hundreds_reg = 4'd2;
            remainder_after_hundreds = product_binary - 200;
        end else if (product_binary >= 100) begin
            product_hundreds_reg = 4'd1;
            remainder_after_hundreds = product_binary - 100;
        end else begin
            product_hundreds_reg = 4'd0;
            remainder_after_hundreds = product_binary;
        end

        if (remainder_after_hundreds >= 90) begin
            product_tens_reg = 4'd9;
            product_units_reg = remainder_after_hundreds - 90;
        end else if (remainder_after_hundreds >= 80) begin
            product_tens_reg = 4'd8;
            product_units_reg = remainder_after_hundreds - 80;
        end else if (remainder_after_hundreds >= 70) begin
            product_tens_reg = 4'd7;
            product_units_reg = remainder_after_hundreds - 70;
        end else if (remainder_after_hundreds >= 60) begin
            product_tens_reg = 4'd6;
            product_units_reg = remainder_after_hundreds - 60;
        end else if (remainder_after_hundreds >= 50) begin
            product_tens_reg = 4'd5;
            product_units_reg = remainder_after_hundreds - 50;
        end else if (remainder_after_hundreds >= 40) begin
            product_tens_reg = 4'd4;
            product_units_reg = remainder_after_hundreds - 40;
        end else if (remainder_after_hundreds >= 30) begin
            product_tens_reg = 4'd3;
            product_units_reg = remainder_after_hundreds - 30;
        end else if (remainder_after_hundreds >= 20) begin
            product_tens_reg = 4'd2;
            product_units_reg = remainder_after_hundreds - 20;
        end else if (remainder_after_hundreds >= 10) begin
            product_tens_reg = 4'd1;
            product_units_reg = remainder_after_hundreds - 10;
        end else begin
            product_tens_reg = 4'd0;
            product_units_reg = remainder_after_hundreds;
        end
    end

    // 百位LED逻辑
    reg [1:0] led_hundreds_reg;

    always @(*) begin
        case (product_hundreds_reg)
            4'd0:    led_hundreds_reg = 2'b00;
            4'd1:    led_hundreds_reg = 2'b01;
            4'd2:    led_hundreds_reg = 2'b10;
            default: led_hundreds_reg = 2'b00;
        endcase
    end

    assign led_hundreds      = led_hundreds_reg;
    assign result_tens_bcd   = product_tens_reg;
    assign result_units_bcd  = product_units_reg;

    // 数码管显示模块
    wire [15:0] x;
    assign x = {a_tens, a_units, b_tens, b_units};

    x7seg x1(
        .x(x), 
        .clk(clk), 
        .clr_n(clr_n), 
        .a_to_g(a_to_g), 
        .an(an)
    );

endmodule
